using System;
using System.Collections ;
using System.Collections.Generic;
namespace sAstar {

    public class Node : IComparable {

        //Chi phi di chuyen, bang tong do dai duong di tu dinh xuat phat den dinh nay
        public int totalCost {
            get {
                return g + h;
            }
            set {
                totalCost = value;
            }
        }

        //Luu chi phi tong cong khi di den node nay
        public int g;

        //Luu tham so Heuristic
        public int h;


        //Toa do
        public int x;
        public int y;


        //Nut dich
        private Node _goalNode;

        //Nut cha (Nut ke truoc trong duong di)
        public Node parentNode;

        //Chi phi can bo ra de di den node nay, mac dinh ta truyen 1
        private int gCost;


        public Node(Node parentNode, Node goalNode, int gCost, int x, int y) {

            this.parentNode = parentNode;
            this._goalNode = goalNode;
            this.gCost = gCost;
            this.x = x;
            this.y = y;
            InitNode();
        }

        private void InitNode() {
            //Cap nhap chi phi tong cong g
            this.g = (parentNode != null) ? this.parentNode.g + gCost : gCost;

            //Cap nhat tham so Heuristic
            this.h = (_goalNode != null) ? (int)Euclidean_H() : 0;
        }

        //Ham Heuristic cho ra tham so h cho biet khoang cach duong chim bay den dinh dich
        private double Euclidean_H() {
            double xd = this.x - this._goalNode.x;
            double yd = this.y - this._goalNode.y;
            return Math.Sqrt((xd * xd) + (yd * yd));
        }

        //So sanh xem 2 Node, node nao "loi" hon neu chon la node tiep theo tren duong di
        public int CompareTo(object obj) {

            Node n = (Node)obj;
            int cFactor = this.totalCost - n.totalCost;
            return cFactor;
        }

        //Xet 2 node trung nhau (kiem tra xem da den dich chua -> dung thuat toan)
        public bool isMatch(Node n) {
            if (n != null)
                return (x == n.x && y == n.y);
            else
                return false;
        }

        //Lay danh sach cac node ma tu do co the de node nay (dung de toi uu hoa duong di)
        public ArrayList GetSuccessors(int[, ,] map, int ID) {
            ArrayList successors = new ArrayList();
            List<int> temp = new List<int>() { 0, 7, 8, 9, 10 }; //List chua cac o cho the di duoc
           
            //Do 8 o xung quanh
            for (int xd = -1; xd <= 1; xd++) {
                for (int yd = -1; yd <= 1; yd++) {
                    //Han che khong cho di xeo
                    if (xd * yd == 0 && x + xd >= 0 && x + xd <= 12 && y + yd >= 0 && y + yd <= 14) {
                        //Kiem tra xem o co di duoc khong 
                        if (temp.Contains(map[ID, x + xd, y + yd])) {
                            //Di chuyen den mot node moi
                            Node n = new Node(this, this._goalNode, 1, x + xd, y + yd);

                            //Kiem tra xem node co phai la node moi hay da den dich!
                            if (!n.isMatch(this.parentNode) && !n.isMatch(this)) {
                                successors.Add(n);
                            }
                        }
                    }
                }
            }
            return successors;
        }
    }
}
